//
//  IpcMessage.h
//  Because the wheel always needs to be reinvented *cough*...
//  This is a poor replacement for BMessage, everyones favorite data container
//  2006, John Wiggins
//
// This program is free software; you can redistribute it and/or modify  
// it under the terms of the GNU General Public License as published by  
// the Free Software Foundation; either version 2 of the License, or     
// (at your option) any later version.                                   
// 
// This program is distributed in the hope that it will be useful,       
// but WITHOUT ANY WARRANTY; without even the implied warranty of        
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         
// GNU General Public License for more details.                          
//     
//     You should have received a copy of the GNU General Public License     
//     along with this program; if not, write to the                         
//         Free Software Foundation, Inc.,                                       
//         59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  
//-------------------------------------------------------------
#ifndef IPC_MESSAGE_H
#define IPC_MESSAGE_H
//-------------------------------------------------------------
#include <vector>

#include "Basics/BasErrors.h"
#include "Basics/BasTypeConstants.h"
#include "Basics/BasTypes.h"
#include "Ipc/IpcPort.h"
//-------------------------------------------------------------
class IpcMessage
{
public:
    uint32      what;

    explicit    IpcMessage              ( uint32 command );
                IpcMessage              ( IpcMessage const & copy );
                ~IpcMessage             ();

    // a sending function
    status_t    SendMessage             ( ipc_port_t port ) const;

    // Add...() functions
    status_t    AddData                 ( char const *name,
                                            type_code type,
                                            void const *data,
                                            ssize_t numBytes,
                                            bool fixedSize = true,
                                            int32 numItems = 1 );
    status_t    AddBool                 ( char const *name, bool aBool );
    status_t    AddInt8                 ( char const *name, int8 anInt8 );
    status_t    AddInt16                ( char const *name, int16 anInt16 );
    status_t    AddInt32                ( char const *name, int32 anInt32 );
    status_t    AddInt64                ( char const *name, int64 anInt64 );
    status_t    AddFloat                ( char const *name, float aFloat );
    status_t    AddDouble               ( char const *name, double aDouble );
    status_t    AddString               ( char const *name, char const *string );
    status_t    AddPointer              ( char const *name, void const *pointer );

    // Find...() functions
    status_t    FindData                ( char const *name,
                                            type_code type,
                                            int32 index,
                                            void const **data,
                                            ssize_t *numBytes ) const;
    status_t    FindData                ( char const *name,
                                            type_code type,
                                            void const **data,
                                            ssize_t *numBytes ) const;
    status_t    FindBool                ( char const *name, bool *aBool );
    status_t    FindBool                ( char const *name, int32 index, bool *aBool );
    status_t    FindInt8                ( char const *name, int8 *anInt8 );
    status_t    FindInt8                ( char const *name, int32 index, int8 *anInt8 );
    status_t    FindInt16               ( char const *name, int16 *anInt16 );
    status_t    FindInt16               ( char const *name,
                                            int32 index,
                                            int16 *anInt16 );
    status_t    FindInt32               ( char const *name, int32 *anInt32 );
    status_t    FindInt32               ( char const *name,
                                            int32 index,
                                            int32 *anInt32 );
    status_t    FindInt64               ( char const *name, int64 *anInt64 );
    status_t    FindInt64               ( char const *name,
                                            int32 index,
                                            int64 *anInt64 );
    status_t    FindFloat               ( char const *name, float *aFloat );
    status_t    FindFloat               ( char const *name,
                                            int32 index,
                                            float *aFloat );
    status_t    FindDouble              ( char const *name, double *aDouble );
    status_t    FindDouble              ( char const *name,
                                            int32 index,
                                            double *aDouble );
    status_t    FindString              ( char const *name, char const **string );
    status_t    FindString              ( char const *name,
                                            int32 index,
                                            char const **string );
    status_t    FindPointer             ( char const *name, void const **pointer );
    status_t    FindPointer             ( char const *name,
                                            int32 index,
                                            void const **pointer );
    
    // Replace...() functions
    status_t    ReplaceData             ( char const *name,
                                            type_code type,
                                            void const *data,
                                            ssize_t numBytes );
    status_t    ReplaceData             ( char const *name,
                                            type_code type,
                                            int32 index,
                                            void const *data,
                                            ssize_t numBytes );
    status_t    ReplaceBool             ( char const *name, bool aBool );
    status_t    ReplaceBool             ( char const *name, int32 index, bool aBool );
    status_t    ReplaceInt8             ( char const *name, int8 anInt8 );
    status_t    ReplaceInt8             ( char const *name, int32 index, int8 anInt8 );
    status_t    ReplaceInt16            ( char const *name, int16 anInt16 );
    status_t    ReplaceInt16            ( char const *name,
                                            int32 index,
                                            int16 anInt16 );
    status_t    ReplaceInt32            ( char const *name, int32 anInt32 );
    status_t    ReplaceInt32            ( char const *name,
                                            int32 index,
                                            int32 anInt32 );
    status_t    ReplaceInt64            ( char const *name, int64 anInt64 );
    status_t    ReplaceInt64            ( char const *name,
                                            int32 index,
                                            int64 anInt64 );
    status_t    ReplaceFloat            ( char const *name, float aFloat );
    status_t    ReplaceFloat            ( char const *name,
                                            int32 index,
                                            float aFloat );
    status_t    ReplaceDouble           ( char const *name, double aDouble );
    status_t    ReplaceDouble           ( char const *name,
                                            int32 index,
                                            double aDouble );
    status_t    ReplaceString           ( char const *name, char const *string );
    status_t    ReplaceString           ( char const *name,
                                            int32 index,
                                            char const *string );
    status_t    ReplacePointer          ( char const *name, void const *pointer );
    status_t    ReplacePointer          ( char const *name, int32 index, void const *pointer );

    // flattening functions
    status_t    Flatten                 ( char *address, ssize_t *numBytes = NULL ) const;
    status_t    Unflatten               ( char const *address );
    ssize_t     FlattenedSize           () const;

    status_t    MakeEmpty               ();
    bool        IsEmpty                 () const;
    
    void        PrintToStream           () const;

    // removal of data
    status_t    RemoveName              ( char const *name );
    status_t    RemoveData              ( char const *name, int32 index = 0 );

private:

    ssize_t     FlattenRecord           ( char *address, int32 index ) const;
    status_t    UnflattenRecord         ( char *address );
    ssize_t     NthFlattenedSize        ( int32 index ) const;
    
    struct tData
    {
        uchar *     data;
        ssize_t     size;
    };
    struct tDataRecord
    {
        char *      name;
        type_code   type;
        tData *     data;
        uint32      size;
        uint32      capacity;
    };

    std::vector<tDataRecord>    mData;
};
//-------------------------------------------------------------
#endif // IPC_MESSAGE_H
//-------------------------------------------------------------
